(function(angular) {
	"use strict";
	angular.module("fs.waf").factory("directChargeService", directChargeService);
	directChargeService.$inject = [ "$q", "ajaxServiceFactory", "modalService", "txnService", "dateService", "arithService" ];
	function directChargeService($q, ajaxServiceFactory, modalService, txnService, dateService, arithService) {
		var ajaxServices = ajaxServiceFactory.buildAjaxService({
			getCurrencyOptions : {
				url : "do/cls/dataList/currencies",
				method : "get"
			},
			getFeeCode : {
				url : "do/cda/feeCode/view",
				method : "post"
			},
			getDchargeCreateOptions : {
				url : "do/cls/dataList/getDchargeCreateOptions",
				method : "get"
			}
		});
		// The Amortize Tenor must be greater than zero for {0} row.
		function validateDirectItem(chargeItems) {
			var messages = [];
			if (chargeItems && chargeItems.length > 0) {
				angular.forEach(chargeItems, function(chargeItem, index) {
					if (chargeItem.amortizeFlag == "Y") {
						if (chargeItem.amortizeTenor <= 0) {
							messages.push({
								msg : "vlidate.amortizetenor.compare",
								args : [ index + 1 ]
							});
						}
					}
				});
			}
			if (messages.length > 0) {
				modalService.openErrorDialogs({
					"messages" : messages
				});
				return false;
			}
			return true;
		}
		
		function getLayout(packageName, packageSuffix, prodType, readonly) {
			return txnService.getLayout(packageName, packageSuffix, readonly, "DIRECTCHARGE", prodType, undefined);
		}

		function initDataOptions() {
			var defer = $q.defer();
			ajaxServices.getDchargeCreateOptions().then(function(response) {
				defer.resolve(response ? response.data : {});
			});
			return defer.promise;
		}

		function deleteDynaparm(layoutConfig) {
			if (layoutConfig) {
				if (layoutConfig.formConfigs && layoutConfig.formConfigs.dcharge) {
					var gridConfigs = layoutConfig.formConfigs.dcharge.gridConfigs;
					txnService.deleteDynaparm(gridConfigs);
				}
			}
			return layoutConfig;
		}

		function getCurrencyOptions() {
			var defer = $q.defer();
			ajaxServices.getCurrencyOptions().then(function(response) {
				defer.resolve(response ? response.data : []);
			}, angular.noop);
			return defer.promise;
		}

		function getFeeCode(param) {
			var defer = $q.defer();
			ajaxServices.getFeeCode(param).then(function(response) {
				defer.resolve(response);
			});
			return defer.promise;
		}

		function feeCodeChanged(chargeItem, directCharge) {
			if (chargeItem._feeCodeConfig && chargeItem._feeCodeConfig.options.data) {
				angular.forEach(chargeItem._feeCodeConfig.options.data, function(item, key) {
					if (chargeItem.feeCode == item.value) {
						chargeItem.itemCcy = item.feeCcy ? item.feeCcy : directCharge.refCcy;
						chargeItem.itemAmt = item.feeValue ? item.feeValue : 0;
						chargeItem.acctCode = item.acctCode;
						if (item.allocCode) {
							chargeItem.allocCode = item.allocCode;
						}
						return;
					}
				});
			}
			if (chargeItem.feeCode) {
				ajaxServices.getFeeCode({
					feeCode : chargeItem.feeCode
				}).then(function(response) {
					chargeItem.amortizeFlag = response.data.amortizeFlag;
					if (chargeItem.amortizeFlag != "Y") {
						chargeItem.amortizeTenor = 0;
					}
				}, angular.noop);
			}
		}

		function crDrChanged(chargeItem, directCharge) {
			if (chargeItem.crDr && !(chargeItem.readonlyFlag == "Y")) {
				angular.forEach(directCharge.chargeItems, function(chargeItem, key) {
					if (chargeItem.$$hashKey == chargeItem.$$hashKey) {
						chargeItem._feeCodeConfig.options.callback = {
							"changed" : "vm.feeCodeChanged"
						};
						if (chargeItem.crDr == "C") {
							chargeItem._feeCodeConfig.options.data = directCharge.crFeeInfo;
						} else if (chargeItem.crDr == "D") {
							chargeItem._feeCodeConfig.options.data = directCharge.drFeeInfo;
						}
						return;
					}
				});
			}
		}

		function prodTypeChanged(directCharge, layoutConfig, packageName, packageSuffix, readonly) {
			var defer = $q.defer();
			getLayout(packageName, packageSuffix, directCharge.prodType, readonly).then(function(layout) {
				defer.resolve(layout);
			});
			return defer.promise;
		}

		function dateChanged(directCharge) {
			if (directCharge) {
				if (directCharge.refEffectiveDate && directCharge.refDueDate) {
					var days = dateService.compareDate(directCharge.refEffectiveDate, directCharge.refDueDate);
					if (days < 0) {
						modalService.openErrorDialogs({
							messages : [ "Reference Due Date should not be before Reference Effective Date." ]
						});
						return;
					} else {
						directCharge.refTenor = days;
					}
				} else if (directCharge.refTenor >= 0) {
					if (directCharge.refEffectiveDate) {
						directCharge.refDueDate = addDays(directCharge.refEffectiveDate, directCharge.refTenor);
					} else if (directCharge.refDueDate) {
						directCharge.refEffectiveDate = addDays(directCharge.refDueDate, 0 - directCharge.refTenor);
					}
				}
			}
		}

		function addDays(date, days) {
			var dateTemp = angular.copy(date);
			var dateResult = dateService.addDays(dateTemp, days);
			return dateResult;
		}

		function refTenorChanged(directCharge) {
			if (directCharge && directCharge.refTenor) {
				if (arithService.gte(0, directCharge.refTenor)) {
					modalService.openErrorDialogs({
						messages : [ "Tenor should be greater than 0." ]
					});
					if (directCharge.refEffectiveDate && directCharge.refDueDate) {
						directCharge.refTenor = dateService.compareDate(directCharge.refEffectiveDate, directCharge.refDueDate);
					}
					return;
				}
				if (directCharge.refEffectiveDate) {
					directCharge.refDueDate = addDays(directCharge.refEffectiveDate, directCharge.refTenor);
				}
			}
		}
		
		function getApCommunity(communityId){
			var ajaxServices = ajaxServiceFactory.buildAjaxService({
				getApCommunity : {
					url : "do/cda/apCommunity/getApCommunityByPk",
					method : "get"
				}
			});
			var defer = $q.defer();
			ajaxServices.getApCommunity({"communityId" : communityId}).then(function(response) {
				defer.resolve(response.data);
			});
			return defer.promise;
		}

		return {
			initDataOptions : initDataOptions,
			getCurrencyOptions : getCurrencyOptions,
			deleteDynaparm : deleteDynaparm,
			validateDirectItem : validateDirectItem,
			getFeeCode : getFeeCode,
			feeCodeChanged : feeCodeChanged,
			crDrChanged : crDrChanged,
			prodTypeChanged : prodTypeChanged,
			dateChanged : dateChanged,
			refTenorChanged : refTenorChanged,
			getLayout : getLayout,
			getApCommunity : getApCommunity
		};
	}
})(angular);
